# -*- coding: utf-8 -*-
import os
import sys
import logging
import asyncio
import signal


path = os.path.dirname(os.path.dirname(__file__))
sys.path.insert(0, path)

from contract_market.server.server import MainProcess  # NOQA

def _except_record(msg):
    logging.error(msg)


# track
def strategy_excepthook(exc_type, exc_value, traceback):
    msg = ' Traceback (most recent call last):\n'
    while traceback:
        filename = traceback.tb_frame.f_code.co_filename
        name = traceback.tb_frame.f_code.co_name
        lineno = traceback.tb_lineno
        msg += ' File "%.500s", line %d, in %.500s\n' % (
            filename, lineno, name)
        traceback = traceback.tb_next
        msg += ' %s: %s\n' % (exc_type.__name__, exc_value)
        _except_record(msg)


class NoCallBack: ...


class GracefulKiller:
    kill_now = False
    name = "callback"

    def __init__(self):
        self._func = None
        signal.signal(signal.SIGINT, self.exit_gracefully)
        signal.signal(signal.SIGTERM, self.exit_gracefully)

    def exit_gracefully(self, signum, frame):
        self.kill_now = True
        self._func()

    def set_callback(self, func):
        self._func = NoCallBack


async def create_app():
    """ """
    killer = GracefulKiller()

    mp = MainProcess(killer)
    engine = mp.start()
    while 1:
        if killer.kill_now:
            break
        await asyncio.sleep(2)
        print("[manager] running .....")
    engine.stop()


def main():
    """ """
    sys.excepthook = strategy_excepthook

    loop = asyncio.get_event_loop()
    try:
        loop.run_until_complete(create_app())
    finally:
        # see: https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.shutdown_asyncgens
        loop.run_until_complete(loop.shutdown_asyncgens())
        loop.close()


def test_main():
    """ 用来测试 """
    killer = GracefulKiller()
    mp = MainProcess(killer)
    engine = mp.start()
    return engine


if __name__ == "__main__":
    '''
    subscribe xt_contract_user-um:sub_user:b1000aa0-9119-4ce7-a963-e7a0fe0055cb:sub.order:push

    TODO:
        1. 下单 对接 下单框架
        2. API 对接 下单框架
        3. 下单量确定
        4. 自成交减仓
        
        5. 支持多市场
        5. 订单簿重构服务
        6. 持仓等API 接 ws
        7. send 连接中断, 服务端timeout

    framework_strategy作为数据源和下单中心
    contract_market 处理策略的业务逻辑

    cm 与 fs 通信
        在constant中定义事件名
        增加到common中的事件引擎
        实现rpc方法, 保持与fs/rpc一致
        在fs/hprose中定义方法, 并注册到rpc
    
    cm 订阅ws数据
        在server/engine中定义并实现on_xx方法
    使用
        1. 开启fs服务:  focus_test
        2. 调用服务：   rpc_test
    '''
    # main()
    test_main()
    pass
